function [varargout] = proto_select(varargin)


persistent newsel
persistent cur_sel
persistent lastfile

global logic nlogic logicmode

    if(nargout > 0)
        varargout{1} = 0;  % indicate normal return
    end;


if(nargin == 0)
    hp = findobj('tag', 'Protocol');
    if(isempty(hp))
        open('proto_select.fig');
        hb = findobj('tag', 'proto_select_reloadbutton');
        if(~isempty(hb))
            set(hb, 'Callback', 'proto_select(''reload'')');
        end;
        
        hp = findobj('tag', 'Protocol');
        hl = findobj('tag', 'listprotocol');
        set(hl, 'String', ''); % clear the list
        % set(hl, 'Selectionmode', 'multiple');
        newsel = [];
        lastfile = [];
        set_logic('init');
        nlogic = 0;
        logicmode = 0;
        cur_sel = 0;
        up = [];
        set_msg(1);
        proto_select('renew'); % when coming in with nothing, get the current list
    else
        figure(hp);
    end;
    return;
end;

directmode = 0;
if(nargin >= 1)
    cmd = varargin{1};
end;
if(nargin >= 2)
    file = varargin{2};
    directmode = 1; % set direct mode to get filename from commandline
end;
c = datac('control');
        newsel = findsel(c);
        length(newsel)
%fprintf(1, 'cmd: %s\n', cmd);
switch(cmd)
    case 'renew'
        c = datac('control');
        PL = get_args(c);
        hl = findobj('tag', 'listprotocol');
        set(hl, 'String', PL);
        set_msg(0);
        set_logic('init')
        return;

    case 'clear'
        hc = findobj('tag', 'CTL');
        set(hc, 'Value', 1); % essentially clear existing selection.
        set_msg(1);
        set_logic('init')
        return;
        

    case 'select'
        c = datac('control');
        newsel = findsel(c);
        hc = findobj('tag', 'CTL');
        set(hc, 'value', newsel);
        set_msg(length(newsel));
        set_logic(cmd);
%        fprintf(1, 'selected %d \n', length(newsel));
        return;
        
    case 'save'
        c = datac('control'); %#ok<NASGU>
        newsel = findsel(c);
        [fn, pn, fi] = uiputfile(slash4OS('SelectionFiles/*.mat'), 'Save Selection in file');
        if(fi == 0)
            if(nargout > 0)
                varargout{1} = 1;
            end;
            return;
        end;
        save([pn fn], 'logic');
        
    case 'open'
        proto_select('clear'); % first clear the unused buffers to avoid confusion
        if(directmode)
            fn = varargin{2};
            pn = 'SelectionFiles/';
        else
            [fn, pn, fi] = uigetfile(slash4OS('SelectionFiles/*.mat'), 'Read Selection File');
        if(fi == 0)
            if(nargout > 0)
                varargout{1} = 1;
            end;
            return;
        end;
        end;
        p = load([pn fn]);
        logic=p.logic;
        logicmode = 1; % signal that we are currently "replay" - so do not save in set_logic.
        for i = 1:length(logic)
            fprintf(1, 'Logic cmd: %s   Logic Selection: %s\n', char(logic{i}(2)), char(logic{i}(1)));
            if(set_sel(char(logic{i}(2))))
                proto_select(char(logic{i}(1)));
            end;
        end;
        lastfile = fn;
        logicmode = 0; % restore logic mode for more selections.
 
    case 'reload' % this reloads the last selected file.
        if(~isempty(lastfile))
            proto_select('open', lastfile);
        end;
  
    case 'reapply'
        if(~isempty(newsel))
            c = datac('control');
            hc = findobj('tag', 'CTL');
            set(hc, 'value', newsel);
            set_msg(length(newsel));
        end;
        return;

    case 'or'
        c = datac('control');
        sel = findsel(c);
        hc = findobj('tag', 'CTL');
        cur_sel = get(hc, 'value');
        newsel = union(sel, cur_sel);
        set(hc, 'value', newsel);
        set_msg(length(sel));
        set_logic(cmd);
        return;

    case 'and'
        c = datac('control');
        sel = findsel(c);
        hc = findobj('tag', 'CTL');
        cur_sel = get(hc, 'value');
        newsel = intersect(sel, cur_sel);
        set(hc, 'value', newsel);
        set_msg(length(sel));
        set_logic(cmd)
        return;

    case 'not'
        c = datac('control');
        sel = findsel(c);
        hc = findobj('tag', 'CTL');
        cur_sel = get(hc, 'value');
        newsel = setdiff(sel, cur_sel);
        set(hc, 'value', newsel);
        set_msg(length(sel));
        set_logic(cmd)
        return;

    case 'andnot' %
        c = datac('control');
        sel = findsel(c);
        hc = findobj('tag', 'CTL');
        cur_sel = get(hc, 'value');
        andsel = intersect(sel, cur_sel); %find those which are both
        newsel = andsel;
        newsel = setxor(cur_sel, andsel);
        set(hc, 'value', newsel);
        set_msg(length(sel));
        set_logic(cmd)
        return;

    case 'xor'
        c = datac('control');
        sel = findsel(c);
        hc = findobj('tag', 'CTL');
        cur_sel = get(hc, 'value');
        newsel = setxor(sel, cur_sel);
        set(hc, 'value', newsel);
        set_msg(length(sel));
        set_logic(cmd)
 

    case 'next_file'
        c = datac('control');
        [dFilename, lFilename] = unique_arg({c.filename});
        sel = getmainselection;
        fn = c(sel).filename; % get current filename selected (at least, first)
        pos = strmatch(fn, dFilename);
        pos = pos + 1;
        if(pos > length(dFilename))
            return;
        else
            fnthis = dFilename{pos}; % the next file in the database.
            hs = findobj('tag', 'listprotocol');
            if(isempty(hs))
                match = [];
                if(nargout > 0)
                    varargout{1} = 1;

                end;
                return;
            end;
            p_sel = get(hs, 'value');
            ma = strmatch(sprintf('File:%s', fnthis), get(hs, 'string'));
            set(hs, 'value', ma);
            proto_select('select'); % selects the file
            if(~isempty(last_logic))
                set(hs, 'value', p_sel);
                proto_select(last_logic); % reapply logic.

            end;

        end;

    case 'exit'
        h = findobj('tag', 'Protocol');
        close(h);
        return;
    otherwise
end;


function [PL] = get_args(c)
[Pro, lpro] = unique_arg({c.protocol});
[EC, lEC] = unique_arg({c.E_C});
[pnd, lpnd] = unique_arg({c.pnd});
[div, ldiv] = unique_arg({c.div});
[dG1, lG1] = unique_arg({c.G1});
[dG2, lG2] = unique_arg({c.G2});
[dCommentary, lCommentary] = unique_arg({c.Commentary});
[dCellType, lCellType] = unique_arg({c.CellType});
[dFilename, lFilename] = unique_arg({c.filename});

for i = 1:length(Pro)
    Pro{i} = ['Pro: ' Pro{i}];
end;

for i = 1:length(EC)
    EC{i} = ['E_C: ' EC{i}];
end;
for i = 1:length(pnd)
    pnd{i} = ['pnd: ' pnd{i}];
end;
for i = 1:length(div)
    div{i} = ['div: ' div{i}];
end;
for i = 1:length(dG1)
    dG1{i} = ['G1:  ' dG1{i}];
end;
for i = 1:length(dG2)
    dG2{i} = ['G2:  ' dG2{i}];
end;
for i = 1:length(dCommentary)
    dCommentary{i} = ['Cmt: ' dCommentary{i}];
end;
for i = 1:length(dCellType)
    dCellType{i} = ['Type:' dCellType{i}];
end;
for i = 1:length(dFilename)
    dFilename{i} = ['File:' dFilename{i}];
end;

PL = [Pro, EC, pnd, div, dG1, dG2, dCommentary, dCellType, dFilename];

return;


function [res, list] = unique_arg(arg)

% from cell array, find unique arguments in list -
% convert numbers to text
% return is cell array
list = convert_arg(arg);
res = unique(list);
return;

function [arg] = convert_arg(arg)
for i = 1:length(arg)
    if(isempty(arg{i}))
        arg{i} = 'missing';
    end;
    if(isnumeric(arg{i}))
        arg{i} = num2str(arg{i});
    end;
end;
return;


function set_logic(cmd)
global logic nlogic logicmode
if(logicmode) % if in replay, don't save
    return;
end;
switch(cmd)
    case 'init'
        nlogic = 0;
        logic={};
    otherwise
        nlogic = nlogic + 1;
        logic{nlogic} = {cmd, get_sel()};
end;
return;
        
function [selstring] = get_sel()
hs = findobj('tag', 'listprotocol');
if(isempty(hs))
    selstring = '';
    return;
end;
sel = get(hs, 'value');
namelist = get(hs, 'string');
selstring = char(namelist(sel));
return;

function [ok] = set_sel(selstring)
ok = 0;
hs = findobj('tag', 'listprotocol');
if(isempty(hs))
    return;
end;
namelist = get(hs, 'string');
s = strmatch(selstring, namelist, 'exact');
if(~isempty(s))
    set(hs, 'value', s);
    ok = 1; % signal success
%    fprintf(1, 'set %d values\n', length(s));
else
% disp 'set nothing'
end;
return;


function [match] = findsel(c)
% find the matched entries in the data base pointed to by c
% with the selections in the drop down list in sel.
%
match = [];
hs = findobj('tag', 'listprotocol');
if(isempty(hs))
    match = [];
    return;
end;
sel = get(hs, 'value'); % find the selected entries
namelist = get(hs, 'string'); % and their names
if(isempty(namelist))
    return;
end;
for j = sel
    name = char(namelist(sel)); % get the first name
    switch(name(1:5))
        case 'E_C: '
            match = strmatch(name(6:end), convert_arg({c.E_C}), 'exact');
        case 'div: '
            match = strmatch(name(6:end), convert_arg({c.div}), 'exact');
        case 'pnd: '
            match = strmatch(name(6:end), convert_arg({c.pnd}), 'exact');
        case 'G1:  '
            match = strmatch(name(6:end), convert_arg({c.G1}), 'exact');
        case 'G2:  '
            match = strmatch(name(6:end), convert_arg({c.G2}), 'exact');
        case 'Pro: '
            match = strmatch(name(6:end), convert_arg({c.protocol}), 'exact');
        case 'Cmt: '
            match = strmatch(name(6:end), convert_arg({c.Commentary}), 'exact');
        case 'Type:'
            match = strmatch(name(6:end), convert_arg({c.CellType}), 'exact');
        case 'File:'
            match = strmatch(name(6:end), convert_arg({c.filename}), 'exact');
        otherwise
    end;
end;

function set_msg(arg) %#ok<INUSD>
%
% display count of selected dataasets in the window
%
hc = findobj('tag', 'CTL');
cur_sel = get(hc, 'value');
ht = findobj('tag', 'Proto_msgwin');
if(isempty(ht))
    return;
end;
set(ht, 'string', sprintf('%4d', length(cur_sel)));
return;









% --- Executes on button press in proto_select_reloadbutton.
function proto_select_reloadbutton_Callback(hObject, eventdata, handles)
% hObject    handle to proto_select_reloadbutton (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)


